using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Resources;

namespace Media_Renamer {
    public partial class MediaLibrary : UserControl {
        private Dictionary<String, MP3File> _library;
        private Dictionary<String, DataGridViewRow> _gridItems;


        private String HEADER_ALBUM = "ALBUM";
        private String HEADER_ARTIST = "ARTIST";
        private String HEADER_COMMENT = "COMMENT";
        private String HEADER_GENRE = "GENREINDEX";
        private String HEADER_TAGVERSION = "TAGVERSION";
        private String HEADER_TITLE = "TITLE";
        private String HEADER_TRACKNO = "TRACKNO";
        private String HEADER_YEAR = "YEAR";
        private String HEADER_FILENAME = "FILENAME";
        private String HEADER_PATH = "PATH";
        private Boolean _updating =false;
        private Boolean _readOnly=false;

        private ResourceManager _rm;
        private ContextMenuStrip contentMenu;
        public MediaLibrary() {
            _rm = new ResourceManager("Media_Renamer.Languages.locale", typeof(MediaLibrary).Assembly);
            InitializeComponent();
            _library = new Dictionary<string, MP3File>();
            _gridItems = new Dictionary<string, DataGridViewRow>();
            initGrid();
        }
        public Boolean Updating {
            get { return _updating; }
            set { _updating = value; }
        }
        

        public Boolean ReadOnly {
            get { return _readOnly; }
            set { _readOnly = value;
            foreach (DataGridViewColumn column in grid.Columns) {
                if (column.Name != HEADER_FILENAME && column.Name != HEADER_TAGVERSION && column.Name != HEADER_PATH) {
                    column.ReadOnly = value;
                }
            }
            }
        }
	
        public void initGrid() {
            grid.Columns.Add(HEADER_FILENAME, _rm.GetString("mediaLibrary.filename", Program.culture));
            grid.Columns.Add(HEADER_TITLE, _rm.GetString("mediaLibrary.title", Program.culture));
            grid.Columns.Add(HEADER_ARTIST, _rm.GetString("mediaLibrary.artist", Program.culture));
            grid.Columns.Add(HEADER_ALBUM, _rm.GetString("mediaLibrary.album", Program.culture));
            grid.Columns.Add(HEADER_TRACKNO, _rm.GetString("mediaLibrary.trackNumber", Program.culture));
            grid.Columns.Add(HEADER_YEAR, _rm.GetString("mediaLibrary.year", Program.culture));
            grid.Columns.Add(HEADER_GENRE, _rm.GetString("mediaLibrary.genre", Program.culture));
            grid.Columns.Add(HEADER_COMMENT, _rm.GetString("mediaLibrary.comment", Program.culture));
            grid.Columns.Add(HEADER_TAGVERSION, _rm.GetString("mediaLibrary.tagVersion", Program.culture));
            grid.Columns.Add(HEADER_PATH, _rm.GetString("mediaLibrary.path", Program.culture));

            grid.Columns[HEADER_FILENAME].ReadOnly = true;
            grid.Columns[HEADER_TAGVERSION].ReadOnly = true;
            grid.Columns[HEADER_PATH].ReadOnly = true;
            foreach (DataGridViewColumn column in grid.Columns) {
                if (column.Name == HEADER_FILENAME) column.Visible = Properties.Settings.Default.column_filename_visible;
                if (column.Name == HEADER_TITLE) column.Visible = Properties.Settings.Default.column_title_visible;
                if (column.Name == HEADER_ARTIST) column.Visible = Properties.Settings.Default.column_artist_visible;
                if (column.Name == HEADER_ALBUM) column.Visible = Properties.Settings.Default.column_album_visible;
                if (column.Name == HEADER_TRACKNO) column.Visible = Properties.Settings.Default.column_trackno_visible;
                if (column.Name == HEADER_YEAR) column.Visible = Properties.Settings.Default.column_year_visible;
                if (column.Name == HEADER_COMMENT) column.Visible = Properties.Settings.Default.column_comment_visible;
                if (column.Name == HEADER_TAGVERSION) column.Visible = Properties.Settings.Default.column_tagVersion_visible;
                if (column.Name == HEADER_PATH) column.Visible = Properties.Settings.Default.column_path_visible;

                //column.ContextMenuStrip = contextHeaderClick;
            }
        }
        public DataGridViewRow initRow(DataGridViewRow row, int position) {
            //row.CreateCells(grid);
            int index = -1;
            if (position >= 0) {
                grid.Rows.Insert(position, row);
                index = position;
            } else {
                 index = grid.Rows.Add(row);
            }
            return grid.Rows[index];
        }
        public void refreshLibrary() {
            foreach (String key in _library.Keys) {
                MP3File mediaItem = _library[key];
                if (_gridItems.ContainsKey(mediaItem.filePath)) {
                    DataGridViewRow row = _gridItems[mediaItem.filePath];
                    mediaItem.reloadInfo();
                    refreshRow(row, mediaItem);
                }
            }
        }
        public void refreshGrid() {
            foreach (String key in _library.Keys) {
                MP3File mediaItem = _library[key];
                refreshMedia(mediaItem);
            }
        }
        public void refreshMedia(MP3File media) {
            MP3File mediaItem = _library[media.filePath];
            if (_gridItems.ContainsKey(mediaItem.filePath)) {
                DataGridViewRow row = _gridItems[mediaItem.filePath];
                refreshRow(row, mediaItem);
            }
        }
        public void refreshRow(DataGridViewRow row, MP3File mediaItem) {
            _updating = true;
            if (row.Cells.Count > 0 && row.Index>-1) {
                row.Cells[HEADER_FILENAME].Value = mediaItem.filename;
                row.Cells[HEADER_PATH].Value = mediaItem.filePath;
                if (mediaItem.UsingV1)
                {
                    row.Cells[HEADER_TITLE].Value = mediaItem.Id3v1Tag.Title;
                    row.Cells[HEADER_ARTIST].Value = mediaItem.Id3v1Tag.Artist;
                    row.Cells[HEADER_ALBUM].Value = mediaItem.Id3v1Tag.Album;
                    row.Cells[HEADER_TRACKNO].Value = mediaItem.Id3v1Tag.TrackNumber;
                    row.Cells[HEADER_YEAR].Value = mediaItem.Id3v1Tag.Year;
                    row.Cells[HEADER_GENRE].Value = mediaItem.Id3v1Tag.GenreIndex;
                    row.Cells[HEADER_COMMENT].Value = mediaItem.Id3v1Tag.Comment;
                    row.Cells[HEADER_TAGVERSION].Value = "ID3v1";

                } else {
                    row.Cells[HEADER_TITLE].Value = mediaItem.Id3v2Tag.Title;
                    row.Cells[HEADER_ARTIST].Value = mediaItem.Id3v2Tag.Artist;
                    row.Cells[HEADER_ALBUM].Value = mediaItem.Id3v2Tag.Album;
                    row.Cells[HEADER_TRACKNO].Value = mediaItem.Id3v2Tag.TrackNumber;
                    row.Cells[HEADER_YEAR].Value = mediaItem.Id3v2Tag.Year;
                    row.Cells[HEADER_GENRE].Value = mediaItem.Id3v2Tag.Genre;
                    row.Cells[HEADER_COMMENT].Value = mediaItem.Id3v2Tag.CommentsList.Count > 0 ? mediaItem.Id3v2Tag.CommentsList[0].Description : "";
                    row.Cells[HEADER_TAGVERSION].Value = "ID3v2";
                }
            }
            _updating = false;
        }

        public DataGridViewRow getRow(String path) {
            return _gridItems[path];
        }
        public DataGridViewRow addFile(String path) {
            if (_gridItems.ContainsKey(path) != true) {
                return addFile(path, -1);
            } else {
                return _gridItems[path];
            }
        }
        public DataGridViewRow addFile(MP3File file) {
            if (_gridItems.ContainsKey(file.filePath) != true) {
                return addFile(file, -1);
            } else {
                return _gridItems[file.filePath];
            }
        }
        public DataGridViewRow addFile(MP3File newFile, int position) {
            if (_gridItems.ContainsKey(newFile.filePath) != true) {
                _updating = true;
                DataGridViewRow newRow = new DataGridViewRow();
                newRow = initRow(newRow, position);
                newRow.ContextMenuStrip = this.contentMenu;
                refreshRow(newRow, newFile);
                _gridItems.Add(newFile.filePath, newRow);
                _library.Add(newFile.filePath, newFile);
                _updating = false;
                return newRow;
            } else {
                return _gridItems[newFile.filePath];
            }
        }
        public DataGridViewRow addFile(String path, int position) {
            if (_gridItems.ContainsKey(path) != true) {
                _updating = true;
                MP3File newFile = new MP3File(path);
                return addFile(newFile,position);
            } else {
                return _gridItems[path];
            }
        }
        public void removeFile(string file) {
            DataGridViewRow row = _gridItems[file];
            grid.Rows.Remove(row);
            _gridItems.Remove(file);
            _library.Remove(file);
        }
        public MP3File[] selectedFiles() {
            MP3File[] selected = new MP3File[grid.SelectedRows.Count];
            for (int i = 0; i < grid.SelectedRows.Count; i++) {
                selected[i] = _library[(String)grid.SelectedRows[i].Cells[HEADER_PATH].Value];
            }
            
            return selected;
        }

       

        private void grid_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
            if (!_updating) {
                DataGridViewRow row = grid.Rows[e.RowIndex];
                if (row.Cells[HEADER_PATH].Value != null) {
                    DataGridViewColumn column = grid.Columns[e.ColumnIndex];
                    MP3File mediaFile = _library[(String)row.Cells[HEADER_PATH].Value];

                    if (column.Name == HEADER_TITLE) {
                        if (mediaFile.UsingV1)
                        {
                            mediaFile.Id3v1Tag.Title = (String)row.Cells[HEADER_TITLE].Value;
                        } else {
                            mediaFile.Id3v2Tag.Title = (String)row.Cells[HEADER_TITLE].Value;
                        }
                    } else if (column.Name == HEADER_ALBUM) {
                        if (mediaFile.UsingV1)
                        {
                            mediaFile.Id3v1Tag.Album = (String)row.Cells[HEADER_ALBUM].Value;
                        } else {
                            mediaFile.Id3v2Tag.Album = (String)row.Cells[HEADER_ALBUM].Value;
                        }
                    } else if (column.Name == HEADER_ARTIST) {
                        if (mediaFile.UsingV1)
                        {
                            mediaFile.Id3v1Tag.Artist = (String)row.Cells[HEADER_ARTIST].Value;
                        } else {
                            mediaFile.Id3v2Tag.Artist = (String)row.Cells[HEADER_ARTIST].Value;
                        }
                    } else if (column.Name == HEADER_TRACKNO) {
                        if (mediaFile.UsingV1)
                        {
                            mediaFile.Id3v1Tag.TrackNumber = (int)row.Cells[HEADER_TRACKNO].Value;
                        } else {
                            mediaFile.Id3v2Tag.TrackNumber = (String)row.Cells[HEADER_TRACKNO].Value;
                        }
                    } else if (column.Name == HEADER_YEAR) {
                        if (mediaFile.UsingV1)
                        {
                            mediaFile.Id3v1Tag.Year = (String)row.Cells[HEADER_YEAR].Value;
                        } else {
                            mediaFile.Id3v2Tag.Year = (String)row.Cells[HEADER_YEAR].Value;
                        }
                    } else if (column.Name == HEADER_COMMENT) {
                        if (mediaFile.UsingV1)
                        {
                            mediaFile.Id3v1Tag.Comment = (String)row.Cells[HEADER_COMMENT].Value;
                        } else {
                            mediaFile.Id3v2Tag.CommentsList[0].Description = (String)row.Cells[HEADER_COMMENT].Value;
                        }
                    }
                    mediaFile.saveInfo();
                }
            }
            
        }

        void menuItem_Click(object sender, EventArgs e) {
            foreach (ToolStripMenuItem menuItem in contextHeaderClick.Items) {
                grid.Columns[(String)menuItem.Tag].Visible = menuItem.Checked;
                if ((String)menuItem.Tag == HEADER_FILENAME)    Properties.Settings.Default.column_filename_visible = menuItem.Checked;
                if ((String)menuItem.Tag == HEADER_TITLE) Properties.Settings.Default.column_title_visible = menuItem.Checked;
                if ((String)menuItem.Tag == HEADER_ARTIST) Properties.Settings.Default.column_artist_visible = menuItem.Checked;
                if ((String)menuItem.Tag == HEADER_ALBUM) Properties.Settings.Default.column_album_visible = menuItem.Checked;
                if ((String)menuItem.Tag == HEADER_TRACKNO) Properties.Settings.Default.column_trackno_visible = menuItem.Checked;
                if ((String)menuItem.Tag == HEADER_YEAR) Properties.Settings.Default.column_year_visible = menuItem.Checked;
                if ((String)menuItem.Tag == HEADER_COMMENT) Properties.Settings.Default.column_comment_visible = menuItem.Checked;
                if ((String)menuItem.Tag == HEADER_TAGVERSION) Properties.Settings.Default.column_tagVersion_visible = menuItem.Checked;
                if ((String)menuItem.Tag == HEADER_PATH) Properties.Settings.Default.column_path_visible = menuItem.Checked;
            }
            Properties.Settings.Default.Save();
            //throw new Exception("The method or operation is not implemented.");
        }
        public override ContextMenuStrip ContextMenuStrip {
            get { return null; }
            set { }
        }

        public ContextMenuStrip ItemContextMenuStrip {
            get { return this.contentMenu; }
            set { this.contentMenu = value;
            foreach (DataGridViewRow row in grid.Rows) {
                foreach (DataGridViewCell cell in row.Cells) {
                    cell.ContextMenuStrip = this.contentMenu;
                }
            }
            }
        }
	

        private void contextHeaderClick_Opening(object sender, CancelEventArgs e) {
            contextHeaderClick.Items.Clear();
            
            foreach (DataGridViewColumn column in grid.Columns) {
                ToolStripMenuItem menuItem = new ToolStripMenuItem();
                menuItem.Checked = column.Visible;
                menuItem.Text = column.HeaderText;
                menuItem.Tag = column.Name;
                menuItem.CheckOnClick = true;
                menuItem.Click += new EventHandler(menuItem_Click);
                contextHeaderClick.Items.Add(menuItem);

            }
        }

        private void grid_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
            if (e.Button == MouseButtons.Right) {
                contextHeaderClick.Show(grid, getColumnLeft(grid.Columns[e.ColumnIndex]) + e.X, e.Y);
            }
        }
        private int getColumnLeft(DataGridViewColumn column) {
            int finalLeft = 0;
            foreach (DataGridViewColumn gridColumn in grid.Columns) {
                if (gridColumn.Visible == true && gridColumn.DisplayIndex < column.DisplayIndex) {
                    finalLeft += gridColumn.Width;
                }
            }
            return finalLeft;
        }
        public void clear() {
            grid.Rows.Clear();
            _library = new Dictionary<string, MP3File>();
            _gridItems = new Dictionary<string, DataGridViewRow>();
        }

        private void grid_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e) {
            List<String> validKeys = new List<string>();
            List<String> invalidKeys = new List<string>();
            foreach (DataGridViewRow row in grid.Rows) {
                validKeys.Add((string)row.Cells[HEADER_PATH].Value);
            }
            foreach (String key in _gridItems.Keys) {
                if (validKeys.Contains(key) != true) {
                    invalidKeys.Add(key);
                }
            }
            foreach (String key in invalidKeys) {
                _gridItems.Remove(key);
                _library.Remove(key);
            }
            
        }
    }
}
